package com.jy.api.controller;

import com.jy.api.dao.*;
import com.jy.api.domain.*;
import com.jy.api.service.InventoryService;
import com.jy.api.service.ProductService;
import com.jy.api.signUpReq.stock.*;
import com.jy.api.util.OpenSearchUtil;
import com.jy.api.util.Result;
import com.jy.api.util.ValidatorUtil;
import com.jy.api.vo.ProductDTO;
import com.jy.api.vo.StoreVo;
import com.jy.api.vo.stock.InventoryDataVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.*;


/**
 * Created by hanxi on 2018/7/5.
 */
@Slf4j
@RestController
@RequestMapping(value = "v1/inv")
public class InventoryController {

    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private ProductDao productDao;
    @Autowired
    private StockReceiptDao stockReceiptDao;
    @Autowired
    private StockTransactionDao stockTransactionDao;
    @Autowired
    private StockCheckOrderDao stockCheckOrderDao;
    @Autowired
    private StoreDao storeDao;
    @Autowired
    private EmployeeDao employeeDao;
    @Autowired
    private ProductService productService;
    @Autowired
    private InventoryDao inventoryDao;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    /**
     * 库存管理首页，获取仓库库存商品列表接口
     *
     * @param storeId 店铺id
     * @param q       商品名称。查询条件，可为空
     * @param page    分页参数,
     * @return 库存商品列表
     */
    @GetMapping(path = "/inventories")
    public ResponseEntity getInventories(@RequestParam String storeId, @RequestParam(name = "q", defaultValue = "") String q, @PageableDefault(size = 10, sort = {"id"}) Pageable page) {

        if (q == null || "".equals(q.trim())) {
            Page<Inventory> result = inventoryService.findByStoreId(storeId, page);
            return ResponseEntity.ok(result);
        } else {
            return new ResponseEntity(OpenSearchUtil.queryProduct(storeId, q.trim(), false), HttpStatus.OK);
        }
    }

    /**
     * 查找吧台的商品
     *
     * @param storeId
     * @param page
     * @return
     */
    @GetMapping(path = "/stock")
    public ResponseEntity getStock(@RequestParam("storeId") String storeId, @PageableDefault(size = 20, sort = {"id"}) Pageable page) {
        return new ResponseEntity(inventoryService.findByStoreIdAndIsStockEnable(storeId, page), HttpStatus.OK);
    }


    /**
     * 更新首页仓库进货价格
     *
     * @param inventoryDataVo
     * @return
     */
    @PostMapping(path = "/update")
    @ResponseBody
    public ResponseEntity updateById(@RequestBody InventoryDataVo inventoryDataVo) {
        inventoryService.updateByStoreId(inventoryDataVo);
        return new ResponseEntity(HttpStatus.OK);
    }

    /**
     * 商品名字搜索(已核查)
     *
     * @param storeId
     * @param q
     * @return
     */

    @GetMapping(path = "search")
    public ResponseEntity searchByName(@RequestParam(name = "storeId") String storeId,
                                       @RequestParam(name = "q", defaultValue = "") String q) {
        try {
            q.trim();
            Store store = storeDao.findOne(storeId);
            if (store == null) {
                return new ResponseEntity("查询失败！店铺信息有误！", HttpStatus.BAD_REQUEST);
            }
            List<Map<String, Object>> products = new ArrayList<>();
            if (ValidatorUtil.isChinese(q)) {
                products = productDao.getProductLikeName(storeId, q);
            } else {
                q = q.toLowerCase();
                products = productDao.getProductLikePinyin(storeId, q);
            }
            return new ResponseEntity(products, HttpStatus.OK);
        } catch (RuntimeException ex) {
            log.error("queryProduct is error==> storeId:{},q:{}", storeId, q, ex);
            return new ResponseEntity("系统运行错误", HttpStatus.INTERNAL_SERVER_ERROR);
        } catch (Exception ex) {
            log.error("queryProduct is error==> storeId:{},q:{}", storeId, q, ex);
            return new ResponseEntity("系统运行错误", HttpStatus.INTERNAL_SERVER_ERROR);
        }

    }


    /**
     * 通过商品ID去查库存/吧台（已经核查）
     * 通过
     *
     * @param productId
     * @param page
     * @return
     */
    @GetMapping(path = "get/product")
    public ResponseEntity getProductById(@RequestParam("bat") String type, @RequestParam("index") String index, @RequestParam("id") String productId, @PageableDefault(size = 10, sort = {"id"}) Pageable page) {
        Product p = productDao.findOne(productId);
        try {
            if (type.equals("bat")) {
                if (index.equals("index")) {
                    return new ResponseEntity(inventoryService.findCountByProduct(productId, page), HttpStatus.OK);
                } else {
                    return new ResponseEntity(inventoryService.findByProduct(productId), HttpStatus.OK);
                }
            }
            if (p == null) {
                return new ResponseEntity("商品信息不存在！", HttpStatus.BAD_REQUEST);
            }
            if (!p.isStockEnabled()) {
                return new ResponseEntity("商品未管理库存！！", HttpStatus.BAD_REQUEST);
            }
            if (index.equals("index")) {
                return new ResponseEntity(inventoryService.findByProductId(productId, page), HttpStatus.OK);
            } else {
                List<Inventory> list = inventoryService.findByPId(productId);
                if (list.size() > 0 || !list.isEmpty()) {
                    return new ResponseEntity(inventoryService.findByPId(productId).get(0), HttpStatus.OK);
                } else {
                    Map<String, String> map = new HashMap<>();
                    map.put("status", "false");
                    return new ResponseEntity(map, HttpStatus.OK);
                }
            }

        } catch (Exception e) {
            log.error("homePage is error==> productId{}", productId, e);
            return new ResponseEntity("系统运行错误", HttpStatus.INTERNAL_SERVER_ERROR);
        }


    }

    /**
     * 仓库出库商品查询
     *
     * @param productId
     * @param
     * @return
     */
    @GetMapping("get-outProduct")
    public ResponseEntity getOutProduct(@RequestParam("id") String productId) {
        return new ResponseEntity(inventoryDao.findByEnabledAndProductId(true, productId), HttpStatus.OK);
    }


    /**
     * 入库
     *
     * @param in
     * @return
     */
    @PostMapping(path = "/stock-in")
    public ResponseEntity stockIn(@RequestBody InventoryInReq in) {
        try {
            return new ResponseEntity(inventoryService.stockIn(in), HttpStatus.OK);
        } catch (Exception e) {
            log.error("stockIn is error=>signUpReq:{}", in, e);
            return new ResponseEntity(new Result(500), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }


    /**
     * 商品出库
     *
     * @param inReq
     * @return
     */
    @PostMapping(path = "/stock-out")
    public ResponseEntity stockOut(@RequestBody InventoryInReq inReq) {
        try {
            return new ResponseEntity(inventoryService.stockOut(inReq), HttpStatus.OK);
        } catch (Exception e) {
            log.error("stoctOut is error=>signUpReq:{}", inReq, e);
            return new ResponseEntity(new Result(500), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 添加规格 新增库存
     *
     * @param in
     * @return
     */
    @PostMapping(path = "/add-capacity")
    public ResponseEntity addNewCapacity(@RequestBody InventoryReqData in) {
        try {
            inventoryService.addNewCapacity(in);
            return new ResponseEntity("添加成功", HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity("添加失败，请重新添加", HttpStatus.BAD_GATEWAY);
        }
    }

    /**
     * 通过商品id去查规格
     *
     * @param productId
     * @return
     */
    @GetMapping(path = "find-capacity")
    public ResponseEntity findCapacity(@RequestParam("productId") String productId, @RequestParam("storeId") String storeId) {
        return new ResponseEntity(inventoryService.findByInvProductId(productId, storeId), HttpStatus.OK);
    }

    /**
     * 通过id隐藏库存数据
     *
     * @param id
     * @return
     */
    @GetMapping(path = "delete-invId")
    public ResponseEntity deleteByInvId(@RequestParam("invId") Long id) {
        try {
            return new ResponseEntity(inventoryService.deleteByInvId(id), HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity("删除失败，请核查后进行删除", HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * 盘点
     * 显示所有商品
     *
     * @param storeId
     * @param page
     * @return
     */
    @GetMapping(path = "findAll-check")
    public ResponseEntity findAllCheck(@RequestParam("id") String storeId, @PageableDefault(size = 20, sort = {"id"}) Pageable page) {
        return new ResponseEntity(inventoryService.findListByStoreId(storeId), HttpStatus.OK);
    }

    /**
     * 盘点商品
     *
     * @param req
     * @return
     */
    @PostMapping(path = "check-in")
    public ResponseEntity checkIn(@RequestBody InventoryCheckReq req) {

        try {
            return new ResponseEntity(inventoryService.checkInOrOut(req), HttpStatus.OK);
        } catch (Exception e) {
            log.error("check-in is error=>signUpReq:{}", req, e);
            return new ResponseEntity(new Result(500), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 得到主纪律
     *
     * @param storeId
     * @param pageable
     * @return
     */
    @GetMapping(path = "get-receipt")
    public ResponseEntity getReceipt(@RequestParam("id") String storeId, @PageableDefault(value = 10, sort = {"addTime"}, direction = Sort.Direction.DESC) Pageable pageable) {

        return new ResponseEntity(stockReceiptDao.findListByLevelAndStoreId(StockLevel.WAREHOUSE, storeId, pageable), HttpStatus.OK);

    }

    /**
     * 通过主记录id去查详情
     *
     * @param invId
     * @param storeId
     * @return
     */
    @GetMapping(path = "get-receiptDetail")
    public ResponseEntity getReceiptDetail(@RequestParam("invId") String invId, @RequestParam("storeId") String storeId) {
        return new ResponseEntity(stockTransactionDao.findListByRefIdAndStoreId(invId, storeId), HttpStatus.OK);
    }

    /**
     * 得到店铺的查询所有盘点记录
     *
     * @param storeId
     * @param pageable
     * @return
     */
    @GetMapping(path = "get-storeCheck")
    public ResponseEntity getStoreCheck(@RequestParam("storeId") String storeId, @PageableDefault(value = 10, sort = {"addTime"}, direction = Sort.Direction.DESC) Pageable pageable) {
        return new ResponseEntity(stockCheckOrderDao.findByStoreIdAndStockLevel(storeId, StockLevel.WAREHOUSE, pageable), HttpStatus.OK);
    }

    /**
     * 库存记录组合查询
     *
     * @param
     * @param pageable
     * @return
     */
    @GetMapping(path = "get-barOrWarehouse")
    public ResponseEntity getTranscationByName(@RequestParam(name = "invId", required = false) String invId, @RequestParam("type") StockType type, @RequestParam("reason") StockChangeReason reason, @RequestParam("storeId") String storeId, @PageableDefault(value = 10, sort = {"addTime"}, direction = Sort.Direction.DESC) Pageable pageable) {
        InventorySerachReq req = new InventorySerachReq();
        req.setInvId(invId);
        req.setReason(reason);
        req.setStoreId(storeId);
        req.setType(type);
        Page<StockChangeTransaction> transactions = inventoryService.findByProductIdAndCapacity(req, pageable);
        if (transactions == null) {
            return new ResponseEntity("无该记录，请重新选择查询条件", HttpStatus.BAD_REQUEST);
        } else {
            return new ResponseEntity(transactions, HttpStatus.OK);
        }

    }

    /**
     * 通过invId和规格查询库存
     *
     * @param invId
     * @param cap
     * @return
     */
    @GetMapping(path = "get-invCa")
    public ResponseEntity getInvCa(@RequestParam("invId") Long invId, @RequestParam("cap") Integer cap) {
        return new ResponseEntity(inventoryDao.findByIdAndCapacity(invId, cap), HttpStatus.OK);
    }

    /**
     * 首页的添加规格
     *
     * @param req
     * @return
     */
    @PostMapping(path = "add-indexCa")
    public ResponseEntity add(@RequestBody CapReq req) {
        try {
            return new ResponseEntity(inventoryService.saveCa(req), HttpStatus.OK);
        } catch (Exception e) {
            log.info("add-indexCa is error" + e);
            return new ResponseEntity("系统错误", HttpStatus.SERVICE_UNAVAILABLE);
        }
    }

   /*----------------------------------分割线-----------------------------------------------*/

    /**
     * 通过商品id去查询商品
     *
     * @param productId
     * @param storeId
     * @param empId
     * @return
     */
    @GetMapping("get-product")
    public ResponseEntity getProduct(@RequestParam("productId") String productId, @RequestParam("storeId") String storeId, @RequestParam("empId") String empId) {
        if (!productDao.findOne(productId).isStockEnabled()) {
            return new ResponseEntity("该商品没管理库存", HttpStatus.BAD_REQUEST);
        }
        if (null == storeDao.findOne(storeId)) {
            return new ResponseEntity("无该店铺信息", HttpStatus.BAD_REQUEST);
        }
        if (null == employeeDao.findOne(empId)) {
            return new ResponseEntity("无该店员信息", HttpStatus.BAD_REQUEST);
        }
        ProductDTO dto = new ProductDTO(productDao.findOne(productId));
        return new ResponseEntity(dto, HttpStatus.OK);
    }

    /**
     * 商品入库
     *
     * @param barReq
     * @return
     */
    @PostMapping("stockIn")
    public ResponseEntity stockIn(@RequestBody StockBarReq barReq) {
        try {
            return new ResponseEntity(productService.stockIn(barReq), HttpStatus.OK);
        } catch (Exception e) {
            log.error("barIn is error=>signUpReq:{}", barReq, e);
            return new ResponseEntity(new Result(500), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 吧台的盘点出入库
     *
     * @param req
     * @return
     */
    @PostMapping("checkBar-product")
    public ResponseEntity checkBarProduct(@RequestBody BarCheckReq req) {
        return new ResponseEntity(productService.checkBarInOrOut(req), HttpStatus.OK);
    }

    /**
     * 通过店铺id和bar识别去查询盘点记录
     *
     * @param storeId
     * @param pageable
     * @return
     */
    @GetMapping("find-barDetail")
    public ResponseEntity findDetail(@RequestParam("storeId") String storeId, @PageableDefault(value = 10, sort = {"addTime"}, direction = Sort.Direction.DESC) Pageable pageable) {
        return new ResponseEntity(stockCheckOrderDao.findByStoreIdAndStockLevel(storeId, StockLevel.BAR, pageable), HttpStatus.OK);
    }


    /**
     * 得到主纪律
     *
     * @param storeId
     * @param pageable
     * @return
     */
    @GetMapping(path = "get-barReceipt")
    public ResponseEntity getBarReceipt(@RequestParam("id") String storeId, @PageableDefault(value = 10, sort = {"addTime"}, direction = Sort.Direction.DESC) Pageable pageable) {

        return new ResponseEntity(stockReceiptDao.findListByLevelAndStoreId(StockLevel.BAR, storeId, pageable), HttpStatus.OK);
    }

    /**
     * 得到所有盘点商品
     *
     * @param storeId
     * @return
     */
    @GetMapping("getList-barProduct")
    public ResponseEntity getListBarProduct(@RequestParam("id") String storeId) {
        return new ResponseEntity(productDao.findListByStoreIdAndEnabledAndStockEnabled(storeId, true, true), HttpStatus.OK);
    }

    /**
     * 组合查询
     *
     * @param
     * @param pageable
     * @return
     */
    @GetMapping("getBar-transaction")
    public ResponseEntity getBarTransaction(@RequestParam("storeId") String id, @RequestParam(name = "productId", required = false) String productId, @RequestParam(name = "phone", required = false) String phone, @RequestParam("type") StockType type, @PageableDefault(value = 10, sort = {"addTime"}, direction = Sort.Direction.DESC) Pageable pageable) {
        BarAssembleReq req = new BarAssembleReq();
        req.setStoreId(id);
        req.setType(type);
        req.setProductId(productId);
        req.setPhone(phone);
        return new ResponseEntity(productService.findListBySkuIdAndTypeAndStockLevel(req, pageable), HttpStatus.OK);
    }

    /**
     * 商品出库
     *
     * @param barReq
     * @return
     */
    @PostMapping("stockOut")
    public ResponseEntity stockOut(@RequestBody StockBarReq barReq) {
        try {
            return new ResponseEntity(productService.stockOut(barReq), HttpStatus.OK);
        } catch (Exception e) {
            log.error("barIn is error=>signUpReq:{}", barReq, e);
            return new ResponseEntity(new Result(500), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 退出登陆并清空授权
     */
    @PostMapping(value = "/logout")
    public void logout(HttpServletRequest request) {
        SecurityContextLogoutHandler handler = new SecurityContextLogoutHandler();
        handler.logout(request, null, null);
    }

    /**
     * 授权接口
     *
     * @param storeId
     * @param principal
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "/authorize")
    public ResponseEntity author(@RequestParam(value = "storeId") String storeId,
                                 Principal principal) {
        try {
            Store store = storeDao.findOne(storeId);
            if (store != null) {
                stringRedisTemplate.opsForValue().set(principal.getName(), storeId);
            } else {
                return new ResponseEntity("店铺不存在", HttpStatus.BAD_REQUEST);
            }
            return new ResponseEntity(HttpStatus.OK);
        } catch (Exception ex) {
            log.error("stock author is error==> principal{}", principal, ex);
            return new ResponseEntity("系统运行错误", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }


    /**
     * 用户店铺库存管理登陆接口
     *
     * @param principal
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "/stock/login")
    public ResponseEntity loginStock(Principal principal) {
        List<StoreVo> storeVos = new ArrayList<>();
        try {
            List<Employee> employees = employeeDao.findByUsernameAndEnabled(principal.getName(), true);
            if (employees.size() == 0) {
                return new ResponseEntity("无对应登陆权限店铺", HttpStatus.BAD_REQUEST);
            }
            List<String> storeIds = new ArrayList<>();
            Map<String, Employee> map = new HashMap<>();
            for (Employee employee : employees) {
                if (employee.getGroup().getRoles().indexOf("ROLE_STOCK") != -1) {
                    storeIds.add(employee.getStoreId());
                    map.put(employee.getStoreId(), employee);
                }
            }
            if (storeIds.size() > 0) {
                List<Store> stores = storeDao.findByIdIn(storeIds);
                for (Store store : stores) {
                    Employee employee = map.get(store.getId());
                    StoreVo storeVo = new StoreVo(employee.getId(), employee.getName(), store.getId(),
                            store.getName(), employee.getCode(), store.getAddTime(), store.getPayMode());
                    storeVos.add(storeVo);
                }
            }
            Collections.sort(storeVos, Comparator.comparing(StoreVo::getAddTime));
            Collections.reverse(storeVos);
            return new ResponseEntity(storeVos, HttpStatus.OK);
        } catch (Exception ex) {
            log.error("login author is error==> principal{}", principal, ex);
            return new ResponseEntity("系统运行错误", HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Autowired
    private DataSourceDao dataSourceDao;

    @GetMapping("deal-data")
    public ResponseEntity dealData() {
        List<Store> store = storeDao.findByMchIdIsNotNull();
        List<DataSource> dataSource = dataSourceDao.findAll();
        List<Store> list = new ArrayList<>();
        for (Store s : store) {
            for (DataSource d : dataSource) {
                if (StringUtils.equals(s.getMchId(), d.getMchId())) {
                    s.setKey(d.getKey());
                    list.add(s);
                }
            }
        }
        storeDao.save(list);
        return ResponseEntity.ok("执行成功");
    }


}










